﻿namespace Mathematics.Expressions
{
    public sealed class Variable:MathExpression
    {
        
        internal Variable(string name)
        {
            Name = name;
            IsMutable = true;
            Value = null;
        }

        internal Variable(string name, bool isMutable, ExpressionValue value)
        {
            Name = name;
            IsMutable = isMutable;
            Value = value;
        }

        #region Public Properties

        public ExpressionValue Value { get; private set; }

        public bool IsMutable { get; private set; }
        public string Name { get; private set; }
        public bool IsSet { get { return Value != null; } }
        public bool IsAssigned { get; internal set; }

        #endregion

        #region Public Methods

        public void Set(ExpressionValue value)
        {
            if (!IsMutable)
                throw new ImmutableVariableException("Constant Variables may not be modified once set.");
            Value = value;
        }

        public override string ToString()
        {
            return Name;
        }

        public override ExpressionValue Evaluate()
        {
            return IsSet ? Value : ExpressionValue.Void;
        }

        protected internal override MathExpression Reduce(out bool didReduce)
        {
            if (IsSet)
            {
                didReduce = true;
                return new Constant(Value);
            }
            else
            {
                didReduce = false;
                return this;
            }
        }

        public override bool CanEvaluate()
        {
            return IsSet;
        }

        #endregion

        #region Static Methods



        #endregion
    }
}
